#!/usr/bin/env python
# Licensed under the MIT license:
# http://www.opensource.org/licenses/mit-license.php 

"""
Actual model (multinomial logit) - depends on R/rpy2.
"""

import cgi
import cgitb  # enable for debugging
cgitb.enable()
from preprocess import gettweets
from preprocess import wordlist
from preprocess import TopicWordsDBPedia
from rpy2.robjects import r

class Model:
  """Initialize R and run actual model."""
  def __init__(self, user, num_tweets):
    # These packages must be on the system, e.g. install.packages() in R
    r('require(zoo, warn.conflicts=FALSE, quietly=TRUE)')  # to avoid messages
    r('require(miscTools, warn.conflicts=FALSE, quietly=TRUE)')  # ditto
    r('require(mlogit, warn.conflicts=FALSE, quietly=TRUE)')
    r('require(R2HTML, warn.conflicts=FALSE, quietly=TRUE)')
    self.user = user
    self.num_tweets = num_tweets
    self.topics = []
    self.rawtweets = gettweets.GetTweets(user, num_tweets)
    #TopicWordsDBPedia.getTopTwoTopicWord
    self.words = wordlist.Wordlist(raw=self.rawtweets, skipread=True)
    self.words.Process()

  def RunModel(self):
    pass
  
  def AssignTopics(self):
    """Assigns topics to the list of tweets for the user."""
    for tweet in self.words.tweets:
      topic = TopicWordsDBPedia.getTopTopicWord(tweet)
      if not topic:
        topic = 'None'
      self.topics.append(topic)
  
  def MakeHTML(self):
    r(('HTMLStart(outdir="/var/www/report", filename="%s", '
       'HTMLframe=FALSE)') % self.user)
    r('HTML(as.title("Model on %s"), append = FALSE)' % self.user)
    r('HTMLhr()')
    # various descriptive variables/stats
    r.assign('words', self.words.worddict.items()[0][1])
    r('HTML("Top 10 words used and number of uses (in past %d tweets)")' %
       self.num_tweets)
    r(('HTML(sort(table(as.factor(sapply(words, `[[`, i=1))), '
       'decreasing=TRUE)[1:10])'))
    r('HTMLhr()')
    r('HTML("Users cleaned up tweets and assigned topics")')
    r.assign('tweets', self.words.tweets)
    r.assign('topics', self.topics)
    r('topics <- sapply(topics, `[[`, i=1)')
    r('HTML("Topic - tweet")')
    r('HTML(as.list(paste(topics, "-", tweets)))')
    r('HTML("Table of topic frequencies")')
    r('HTML(round(prop.table(table(topics)), digits=2))')
    r('HTMLhr()')
    # "backup model" - just summing the logs of positions of topics to score
    # sum(log(y[newx=="z"]))
    r('HTML("Topic scores")')
    r('num <- 1:length(topics)')
    r('unique.topics <- unique(topics)')
    r('topic.scores <- rep(0, length(unique.topics))')
    r(('for (i in 1:length(unique.topics)) { '
       '  topic.scores[i] <- sum(log(num[topics == unique.topics[i]])) }'))
    r(('topic.scores.pct <- sapply(topic.scores, '
       'function(x) { x / sum(topic.scores) })'))
    r('unique.topics <- unique.topics[sort(topic.scores.pct, index.return=TRUE, decreasing=TRUE)$ix]')
    r('topic.scores.pct <- sort(topic.scores.pct, decreasing=TRUE)')
    r('HTML(as.table(cbind(unique.topics, round(topic.scores.pct, digits=2))))')
    # and now the actual multinomial logit model
    # DOESN'T WORK DATA TOO BAD COMMENTING OUT "singular matrix" convergence...
    """
    r('topics <- c("None", topics)')  # hack in case no None's, good enough...
    # linear model
    r('num <- 1:length(topics)')
    r(('mldata1 <- mlogit.data(data.frame(cbind(topics, num)), '
       'choice="topics", shape="wide")'))
    r('HTML(mldata1)')  # TODO remove
    r('try(mlogit.model1 <- mlogit(topics ~ num, data=mldata1, reflevel="None"))')
    r('HTML("Model with linear tweet count")')
    r('try(HTML(summary(mlogit.model1)))')
    # logarithmic model
    r('numl <- log(1:length(topics))')
    r(('mldata2 <- mlogit.data(data.frame(cbind(topics, numl)), '
       'choice="topics", shape="wide")'))
    r('try(mlogit.model2 <- mlogit(topics ~ numl, data=mldata2, reflevel="None"))')
    r('HTML("Model with logarithmic tweet count")')
    r('try(HTML(summary(mlogit.model2)))')
    # for reporting we want to predict the future, e.g. tweets beyond current
    r('num <- c(num, length(num) + 1)')
    """

    """keeping below as example if we need a plot later
    r('HTML("A plot")')
    r('png("/var/www/report/%s.png")' % self.user)
    r('plot(1:10)')
    r('dev.off()')
    r('HTMLInsertGraph("%s.png", caption="Awesomeness")' % self.user)"""
    
    r('HTMLStop()')
